x = {'吕布', '关羽'}
print(type(x))  # <class 'set'>

y = {"吕布": "口口布", "关羽": "关习习"}
print(type(y))  # <class 'dict'>

# 字典取值
print(y["吕布"])  # 口口布

# 新增键值对
y["刘备"] = '刘baby'
print(y)  # {'吕布': '口口布', '关羽': '关习习', '刘备': '刘baby'}

# 创建字典的方法
dict1 = {'吕布': '口口布', '关羽': '关习习', '刘备': '刘baby'}
dict2 = dict(吕布="口口布", 关羽="关习习", 刘备="刘baby")
dict3 = dict([("吕布", "口口布"), ("关羽", "关习习"), ("刘备", "刘baby")])
dict4 = dict({'吕布': '口口布', '关羽': '关习习', '刘备': '刘baby'})
# 混合方法
dict5 = dict({'吕布': '口口布', '关羽': '关习习'}, 刘备="刘baby")
dict6 = dict(zip(['吕布', '关羽', '刘备'], ['口口布', '关习习', '刘baby']))

# [('吕布', '口口布'), ('关羽', '关习习'), ('刘备', '刘baby')]
print(list(zip(['吕布', '关羽', '刘备'], ['口口布', '关习习', '刘baby'])))
print(dict1 == dict2 == dict3 == dict4 == dict5 == dict6)  # True

# 字典-增
# fromkeys(iterable[, values])
d = dict.fromkeys("Fish", 250)
print(d)  # {'F': 250, 'i': 250, 's': 250, 'h': 250}
# 修改存在的 key
d['F'] = 70
print(d)  # {'F': 70, 'i': 250, 's': 250, 'h': 250}
# 新增key
d['C'] = 67
print(d)  # {'F': 70, 'i': 250, 's': 250, 'h': 250, 'C': 67}

# 字典-删
# pop(key[, default])
print(d.pop('s'))  # 250
print(d)  # {'F': 70, 'i': 250, 'h': 250, 'C': 67}

# pop 一个不存在的 key 会抛出异常
# print(d.pop('够'))  # KeyError: '够'
# 通过指定默认值，避免抛出异常
print(d.pop('够', '没有狗'))  # 没有狗

# 3.7 前：随机删除一个键值对，因此这个版本字典是没有顺序的
# 3.7 后：删除最后一个键值对
print(d.popitem())  # ('C', 67)
print(d)  # {'F': 70, 'i': 250, 'h': 250}

# 删除指定的key
del d['i']
print(d)  # {'F': 70, 'h': 250}

# 删除字典对象
del d
# print(d)  # NameError: name 'd' is not defined

# clear
d = dict.fromkeys("Fish", 250)
d.clear()
print(d)  # {}

# 改
d = dict.fromkeys("FishC")
print(d)  # {'F': None, 'i': None, 's': None, 'h': None, 'C': None}
d['s'] = 115
print(d)  # {'F': None, 'i': None, 's': 115, 'h': None, 'C': None}

# 想要同时修改多个键值对呢？
# update([other]) : 可以同时传入多个键值对，也可以传入一个字典，也可以传入一个包含键值对的可迭代对象
d.update({'i': 105, 'h': 104})
print(d)  # {'F': None, 'i': 105, 's': 115, 'h': 104, 'C': None}

d.update(F='70', C='67')
print(d)  # {'F': '70', 'i': 105, 's': 115, 'h': 104, 'C': '67'}

# 查
print(d['C'])  # 67
# print(d['不存在的key'])  # KeyError: '不存在的key'
# 通过 d['x']的方式可能报错，体验不好
# get(key [, default])
print(d.get('g', '这里没有g'))  # 这里没有g

# setdefault(key[, default]) 查询一个key是否存在字典中，如果在则返回value，如果不在则给它指定一个新的value
# 因为 C 存在，所以直接返回67
print(d.setdefault('C', 'code'))  # 67
# C 的 value 没有变化
print(d)  # {'F': '70', 'i': 105, 's': 115, 'h': 104, 'C': '67'}

print(d.setdefault('gg', 'code'))  # code
print(d)  # {'F': '70', 'i': 105, 's': 115, 'h': 104, 'C': '67', 'gg': 'code'}

# items()：获取键值对的视图对象
# keys()：获取key的视图对象
# values()：获取value的视图对象
# 的视图对象：字典发生变化的时候，视图对象也会跟随改变
keys = d.keys()
print(keys)  # dict_keys(['F', 'i', 's', 'h', 'C', 'gg'])
values = d.values()
print(values)  # dict_values(['70', 105, 115, 104, '67', 'code'])
items = d.items()
print(items)  # dict_items([('F', '70'), ('i', 105), ('s', 115), ('h', 104), ('C', '67'), ('gg', 'code')])

# 修改字典内容
d.pop('gg')

# gg 没有了
print(d)  # {'F': '70', 'i': 105, 's': 115, 'h': 104, 'C': '67'}
print(keys)  # dict_keys(['F', 'i', 's', 'h', 'C']) 跟随变化
print(values)  # dict_values(['70', 105, 115, 104, '67']) 跟随变化
print(items)  # dict_items([('F', '70'), ('i', 105), ('s', 115), ('h', 104), ('C', '67')]) 跟随变化

# 浅拷贝
e = d.copy()
print(e)  # {'F': '70', 'i': 105, 's': 115, 'h': 104, 'C': '67'}

print(len(d))  # 5

# 使用 in 跟 not in 判断某个key是否存在字典中
print('gg' in d)  # False
print('gg' not in d)  # True
print('F' in d)  # True

# 通过 list 转化为列表，只是把所有的key转列表
print(list(d))  # ['F', 'i', 's', 'h', 'C']

print(list(d.values()))  # ['70', 105, 115, 104, '67']

# 得到一个 keys() 构成的迭代器
iter1 = iter(d)
print(list(iter1))  # ['F', 'i', 's', 'h', 'C']

print(list(reversed(d.values())))  # ['67', 104, 115, 105, '70']

# 字典嵌套：某个字典的value是另一个字典
d = {"吕布": {"语文": 60, "数学": 70, "英语": 80}, "关羽": {"语文": 80, "数学": 90, "英语": 70}}
print(d["吕布"]['数学'])  # 70

# 嵌套列表
d = {"吕布": [60, 70, 80], "关羽": [80, 90, 70]}
print(d["吕布"][1])  # 70

# 字典推导式
d = {'F': 70, 'i': 105, 's': 115, 'h': 104, 'C': 67}
# 把 d 中的 key-value 对交换顺序之后生成新的 map
b = {v: k for k, v in d.items()}
print(b)  # {70: 'F', 105: 'i', 115: 's', 104: 'h', 67: 'C'}

c = {v: k for k, v in d.items() if v > 100}
print(c)  # {105: 'i', 115: 's', 104: 'h'}

# 循环字符串 FishC 中的每个字符x,调用函数 ord(x)生成x的编码值y，按照 key 为 x，value 为 y的方式组成一个 dict
d = {x: ord(x) for x in "FishC"}
print(d)  # {'F': 70, 'i': 105, 's': 115, 'h': 104, 'C': 67}

d = {x: ord(x) for x in 'swordPig'}
print(d)  # {'s': 115, 'w': 119, 'o': 111, 'r': 114, 'd': 100, 'P': 80, 'i': 105, 'g': 103}

d = {x: y for x in [1, 3, 5] for y in [2, 4, 6]}
print(d)  # {1: 6, 3: 6, 5: 6}

odd = [1, 3, 5]
even = [2, 4, 6]
d2 = {}
for x in odd:
    print("外层循环 {}".format(x))
    for y in even:
        print("内层循环 {}".format(y))
        d2[x] = y
print(d2)  # {1: 6, 3: 6, 5: 6}
# 外层循环 1
# 内层循环 2
# 内层循环 4
# 内层循环 6    因为 dict 的 key 不能重复，相同 key 映射不同的 value 的时候以最新的 value 这里就是 6

# 外层循环 3
# 内层循环 2
# 内层循环 4
# 内层循环 6    因为 dict 的 key 不能重复，相同 key 映射不同的 value 的时候以最新的 value 这里就是 6

# 外层循环 5
# 内层循环 2
# 内层循环 4
# 内层循环 6    因为 dict 的 key 不能重复，相同 key 映射不同的 value 的时候以最新的 value 这里就是 6
# {1: 6, 3: 6, 5: 6}
